/**
 *  学习目标：Todos 案例
 *    1. 类组件改造成函数组件
 *    2. 拆分函数组件(头部，主体，底部)
 *    3. 初始化列表数据，并渲染到主体组件中
 *    4. 主体 - 根据 id 删除数据
 *    5. 主体 - 根据 id 更新完成状态
 *    6. 底部 - 删除已完成任务
 *    7. 底部 - 计算剩余任务数量
 *    8. 底部 - 高亮切换效果
 *    9. 主体 - 计算显示列表(全部显示/未完成/已完成)
 *    10. 主体 - 计算全选状态，切换全选状态
 *    11. 头部 - 受控组件，获取数据，按回车键，新增待办任务
 *    12. 数据初始化时 - 获取本地存储数据
 *    13. 数据更新时 - 设置本地存储数据
 */
import { useEffect, useMemo, useState } from 'react'
import { useDispatch, useSelector } from 'react-redux'
import {
  addTodo,
  changeCheckAll,
  changeCompleted,
  changeType,
  clearCompleted,
  delById,
  Todo,
  TodoState,
} from './store'
import './styles/base.css'
import './styles/index.css'

export default function App() {
  // 数据更新时 - 设置本地存储数据
  const { list, type } = useSelector((state: TodoState) => state)

  // 数据更新时 - 设置本地存储数据
  useEffect(() => {
    localStorage.setItem('todos-list', JSON.stringify(list))
    localStorage.setItem('todos-type', type)
  }, [list, type])

  return (
    <>
      <section className='todoapp'>
        {/* 头部 */}
        <Header />
        {/* 主体 */}
        <Main />
        {/* 底部 */}
        <Footer />
      </section>
    </>
  )
}

// function Card() {
//   const [count, setCount] = useState(0)
//   return (
//     <div>
//     </div>
//   )
// }

function Header() {
  // 受控组件，获取数据
  const [content, setContent] = useState('')
  const dispatch = useDispatch()

  // 按回车键添加新 todo
  const onKeyUp = (e: React.KeyboardEvent<HTMLInputElement>) => {
    if (e.key.toLowerCase() === 'enter') {
      // console.log('按下回车键，要发布内容', content)
      // 非空判断
      if (!content.trim()) return alert('请输入内容后发布~')
      // 准备好 todo 数据
      const todo: Todo = { id: Date.now(), content: content.trim(), completed: false }
      // dispatch 添加 todo 到 redux 中
      dispatch(addTodo(todo))
      // 发布完成后清空
      setContent('')
    }
  }
  return (
    <header className='header'>
      <h1>todos</h1>
      <input
        value={content}
        onChange={(e) => setContent(e.target.value)}
        // 🔔 事件对象类型提示技巧，写成箭头函数传参的写法，鼠标悬停 e 就能获取 事件对象 的类型提示
        onKeyUp={(e) => onKeyUp(e)}
        className='new-todo'
        placeholder='What needs to be done?'
        autoFocus
      />
    </header>
  )
}

function Main() {
  const { list, type } = useSelector((state: TodoState) => state)
  const dispatch = useDispatch()

  // 根据 type值 计算显示列表(全部显示/未完成/已完成) (相当于Vue的Computed计算缓存)
  const showList = useMemo(() => {
    console.log('重新计算展示列表')
    if (type === 'active') {
      return list.filter((v) => !v.completed)
    } else if (type === 'completed') {
      return list.filter((v) => v.completed)
    } else {
      return list
    }
  }, [list, type])

  // 计算全选状态 - useMemo缓存计算结果(相当于Vue的Computed计算缓存)
  const isCheckAll = useMemo(() => {
    console.log('重新计算全选状态')
    return list.length !== 0 && list.every((v) => v.completed)
  }, [list])

  const [count, setCount] = useState(0)

  return (
    <section className='main'>
      <h3>count:{count}</h3>
      <button onClick={() => setCount(count + 1)}>点击+1</button>
      <input
        id='toggle-all'
        className='toggle-all'
        checked={isCheckAll}
        onChange={() => dispatch(changeCheckAll(!isCheckAll))}
        type='checkbox'
      />
      <label htmlFor='toggle-all'>Mark all as complete</label>
      <ul className='todo-list'>
        {showList.map((item) => (
          <li key={item.id} className={item.completed ? 'completed' : ''}>
            <div className='view'>
              <input
                className='toggle'
                checked={item.completed}
                onChange={() => dispatch(changeCompleted(item.id))}
                type='checkbox'
              />
              <label>{item.content}</label>
              <button className='destroy' onClick={() => dispatch(delById(item.id))}></button>
            </div>
            <input className='edit' />
          </li>
        ))}
      </ul>
    </section>
  )
}

function Footer() {
  const dispatch = useDispatch()
  const { list, type } = useSelector((state: TodoState) => state)

  // 7. 底部 - 计算剩余任务数量
  const leftCount = list.filter((v) => !v.completed).length

  return (
    <footer className='footer'>
      <span className='todo-count'>
        <strong>{leftCount}</strong> item left
      </span>
      <ul className='filters'>
        <li>
          <a
            onClick={() => dispatch(changeType('all'))}
            className={type === 'all' ? 'selected' : ''}
            href='#/'
          >
            All
          </a>
        </li>
        <li>
          <a
            onClick={() => dispatch(changeType('active'))}
            className={type === 'active' ? 'selected' : ''}
            href='#/active'
          >
            Active
          </a>
        </li>
        <li>
          <a
            onClick={() => dispatch(changeType('completed'))}
            className={type === 'completed' ? 'selected' : ''}
            href='#/completed'
          >
            Completed
          </a>
        </li>
      </ul>
      <button className='clear-completed' onClick={() => dispatch(clearCompleted())}>
        Clear completed
      </button>
    </footer>
  )
}
